#ifndef __GE_SCENEMANAGER_H__
#define __GE_SCENEMANAGER_H__

#include "GE_Base.h"
///SceneManager is built atop Renderer. It adds basic features like frustum culling/octree/sorting/etc.. to optimise rendering of a scene. Custom SceneManagers can be created and registered before initilisation to be used instead of the default SceneManager provided. SceneManager is designed with rendering/collission-detection in mind.  It supports inclusion of MeshInstances, Lights, Collission Objects. The default SceneManager manages MeshInstances and will automatically delete them during shutdown or when the clearScene() function is called.
namespace Syp
{
class SYPAPI SceneManager
{
public:
	///Defines the number of lights which should affect **PER** object. The lights which affect the object are determined by their distance from the object. The numLights closest to the object will light it. This does not in anyway affect the total number of lights you can have in a scene.
	void setNumLightsPerObj(PByte numLights);

	static void initSceneManager();
	static void releaseSceneManager();

	static SceneManager& getSceneManager();
	///Starts drawing the frame and gives commands to the GPU to keep it busy
	void beginDrawing();
	///Tells the GPU to swap the buffers. "Listen here Renderer, ive been waiting for a long time, so finish up already!"
	void endDrawing();
	///Sets the camera to be used for rendering the scene
	void setActiveCamera(Camera* cam);
	///Returns a pointer to active camera
	Camera* getActiveCamera();
	///Clears the entire scene of all MeshInstances/Lights. Also deletes all MeshInstances currently in the SceneManager.All pointers to existing MeshInstances should not be used. Im abit shaky on the SceneManager deleting the MeshInstances but clearScene() is sort of a RESET function and should take care of everything. Might change if i can find a good reason to.
	void clearScene();
	///Dumps all contents of RenderQue into log file.
	void dumpRenderQue();
	///Adds a light to the scene
	void addLight(Light* l);
	///Removes a light from the scene, Light is not deleted, user should remember to delete it.
	void removeLight(Light* l);

protected:
	///////////////////////////////////////New Mode///////////////////////////////////////////////////////////////
	///These are the instances to be drawn. All detail on how to draw them is available	for analysing the best way to sort them for drawing.
	///Should change to set/sortedVector.
	///Normal drawing
    std::vector<MeshInstance*> Instances;
	std::vector<Light*> Lights;

	std::set<Renderable> renderables;
	///Ortho mode
	//std::list<MeshInstance*> OverLays;
	
private:
	PByte lightsPerObj;
	friend struct MeshInstance;
	///Adds a MeshInstance into the scene. 
	void addInstance(MeshInstance* mi);
	///Removes a MeshInstance from the scene. 
	void removeInstance(MeshInstance* mi);
	SceneManager();
	~SceneManager();
	static SceneManager* sm;
	Renderer* rnd;
	///Pointer to the active camera
	Camera* activeCamera;
	///This variable stores whether or not the SceneManager is currently being clearing the scene. This enables us to ignore removeInstance calls by AMeshInstance destructors which screw up the iterators being used in clearScene().
	bool clearingScene;

};
}
#endif //__GE_SCENEMANAGER_H__

